package com.transpot.service.impl.driver;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.transpot.entry.car.Car;
import com.transpot.entry.car.CarDriver;
import com.transpot.entry.driver.Driver;
import com.transpot.entry.driver.DriverPicture;
import com.transpot.entry.driver.DriverVO;
import com.transpot.entry.driver.Picture;
import com.transpot.mapper.car.CarDriverMapper;
import com.transpot.mapper.car.CarMapper;
import com.transpot.mapper.driver.DriverMapper;
import com.transpot.mapper.driver.DriverPictureMapper;
import com.transpot.mapper.driver.PictureMapper;
import com.transpot.service.driver.DriverService;
import com.transpot.utils.CommonConstant;
import com.transpot.utils.UploadUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 司机类的service层实现类
 */
@Service
public class DriverServiceImpl extends ServiceImpl<DriverMapper, Driver> implements DriverService {
    @Autowired
    private DriverMapper driverMapper;
    @Autowired
    private DriverPictureMapper driverPictureMapper;
    @Autowired
    private PictureMapper pictureMapper;
    @Autowired
    private CarDriverMapper carDriverMapper;
    @Autowired
    private CarMapper carMapper;
    /**
     * 司机注册的方法实现
     * @param driver
     */
    @Override
    public void registerDriver(Driver driver) {
        //设置账号为司机手机号
        driver.setUsername(driver.getPhone());
        //设置密码为系统默认密码
        driver.setPassword(CommonConstant.DEFAULT_PASSWORD);
        //设置创建时间和修改时间为当前
        driver.setCreateTime(LocalDateTime.now());
        driver.setUpdateTime(LocalDateTime.now());
        //调用mapper层保存司机
        driverMapper.insert(driver);
    }

    /**
     * 拼装DriverVO分页对象方法
     * @param driverIPage
     * @return
     */
    @Override
    public Page<DriverVO> getDriverVO(IPage<Driver> driverIPage) {
        //创建一个容器存处理好的DriverVO对象
        List<DriverVO> driverVOS = new ArrayList<>();
        //遍历分页对象里的每一条记录
        for (int i = 0; i < driverIPage.getRecords().size(); i ++) {
            //获取到当前的司机对象
            Driver driver = driverIPage.getRecords().get(i);
            //创建一个新的driverVO对象
            DriverVO driverVO = new DriverVO();
            //把driver中的司机信息存入driverVO对象中
            BeanUtils.copyProperties(driver, driverVO);
            //获得司机的图片信息
            //创建司机图片信息中间类条件查询对象
            LambdaQueryWrapper<DriverPicture> driverPictureLambdaQueryWrapper = new LambdaQueryWrapper<>();
            //设置条件为与司机的主键相同
            driverPictureLambdaQueryWrapper.eq(DriverPicture::getDriverId, driver.getId());
            //根据条件查询到司机和图片信息的中间类对象
            DriverPicture driverPicture = driverPictureMapper.selectOne(driverPictureLambdaQueryWrapper);
            //获取图片信息的主键
            Integer pictureId = driverPicture.getPictureId();
            //根据图片信息主键查询图片信息
            Picture picture = pictureMapper.selectById(pictureId);
            //把图片信息存入到driverVO对象中
            driverVO.setImgUrl1(picture.getImgUrl1());
            driverVO.setImgUrl2(picture.getImgUrl2());
            driverVO.setImgUrl3(picture.getImgUrl3());
            driverVO.setImgUrl4(picture.getImgUrl4());
            driverVO.setImgUrl5(picture.getImgUrl5());

            //获取和司机关联的车辆信息
            //创建司机与车辆信息的中间类条件查询对象
            LambdaQueryWrapper<CarDriver> carDriverLambdaQueryWrapper = new LambdaQueryWrapper<>();
            //设置查询条件为与司机的主键相同
            carDriverLambdaQueryWrapper.eq(CarDriver::getDriverId, driver.getId());
            //查询司机与车辆信息中间类的对象列表
            List<CarDriver> carDriverList = carDriverMapper.selectList(carDriverLambdaQueryWrapper);
            //创建汽车列表，用来存所有的车辆信息
            List<Car> carList = new ArrayList<>();
            //遍历司机与车辆信息中间类列表，获得所有的车辆主键
            for (CarDriver carDriver : carDriverList) {
                //获得汽车主键
                Integer carId = carDriver.getCarId();
                //根据主键查询车辆信息
                Car car = carMapper.selectById(carId);
                //把车辆存入列表中
                carList.add(car);
            }
            //把汽车列表存储到driverVO对象中
            driverVO.setCarList(carList);

            //设置驾照状态变量
            //得到驾照到期时间
            Date currentDate = driver.getExp();
            //得到当前时间
            //设置日期类型转换格式
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //获得日期对象
            Date nowDate = new Date();
            //转换日期对象格式
            sdf.format(nowDate);
            //获得两个日期之间的差值，先转成毫秒再做运算，最后再转成日期
            int days = (int) ((currentDate.getTime() - nowDate.getTime()) / (1000*3600*24));
            //如果日期差值大于等于30，则状态为正常
            if (days >= 30) {
                driverVO.setStatus(0);
            } else if (days < 30 && days > 0) { //如果日期差值小于30且大于0，则为即将到期
                driverVO.setStatus(1);
            } else { //如果小于0则为已经到期
                driverVO.setStatus(2);
            }
            //把driverVO对象保存到driverVOS列表中
            driverVOS.add(driverVO);
        }
        //创建新的分页对象
        Page<DriverVO> driverVOIPage = new Page<>(driverIPage.getCurrent(), driverIPage.getSize());
        //设置查询总条数
        driverVOIPage.setTotal(driverIPage.getTotal());
        //设置查询记录
        driverVOIPage.setRecords(driverVOS);
        //返回结果
        return driverVOIPage;
    }

    /**
     * 根据司机主键删除司机方法实现
     * @param id
     */
    @Override
    public void deleteDriverById(Integer id) {
        //查出该司机信息用来在后边比对车辆所有人使用
        Driver driver = driverMapper.selectById(id);
        //删除司机与图片信息的关联
        //设置司机和照片中间类条件查询对象
        LambdaQueryWrapper<DriverPicture> driverPictureLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //设置查询条件为与司机主键相同
        driverPictureLambdaQueryWrapper.eq(DriverPicture::getDriverId, id);
        //查询满足条件的中间类对象
        DriverPicture driverPicture = driverPictureMapper.selectOne(driverPictureLambdaQueryWrapper);
        //获取到图片信息主键
        Integer pictureId = driverPicture.getPictureId();
        //根据图片主键删除图片信息
        pictureMapper.deleteById(pictureId);
        //根据中间类条件查询对象删除掉司机与图片中间类的关联信息
        driverPictureMapper.delete(driverPictureLambdaQueryWrapper);

        //删除司机与车辆信息的关联
        //创建司机和车辆中间类条件查询对象
        LambdaQueryWrapper<CarDriver> carDriverLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //设置查询条件为与司机主键一致
        carDriverLambdaQueryWrapper.eq(CarDriver::getDriverId, id);
        //查询满足条件的中间类对象
        List<CarDriver> carDriverList = carDriverMapper.selectList(carDriverLambdaQueryWrapper);
        //遍历所有的中间类对象
        for (CarDriver carDriver : carDriverList) {
            //获得车辆信息主键
            Integer carId = carDriver.getCarId();
            //根据主键查询车辆信息
            Car car = carMapper.selectById(carId);
            //判断车辆的所有人
            if (driver.getName().equals(car.getPeople())) {
                //删除该车辆信息
                carMapper.deleteById(carId);
            }
        }
        //删除司机与车辆的关联信息
        carDriverMapper.delete(carDriverLambdaQueryWrapper);

        //删除司机信息
        driverMapper.deleteById(id);
    }

    /**
     * 修改司机信息方法(未改变图片信息)
     * @param driverJson
     * @param carList
     */
    @Override
    public void updateDriver(String driverJson, String carList) {
        //创建json转化对象
        ObjectMapper mapper = new ObjectMapper();
        //把json字符串转换成对象
        Driver driver = null;
        try {
            driver = mapper.readValue(driverJson, Driver.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        //把json字符串转化成对象数组
        List<Car> newCarList = JSONObject.parseArray(carList, Car.class);
        //修改司机信息
        driverMapper.updateById(driver);
        //根据司机主键查询司机车辆中间关系
        LambdaQueryWrapper<CarDriver> carDriverLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //设置查询条件为司机主键
        carDriverLambdaQueryWrapper.eq(CarDriver::getDriverId, driver.getId());
        //根据删除条件删除所有的该司机与车辆的关联
        carDriverMapper.delete(carDriverLambdaQueryWrapper);
        //建立新的司机与车辆关系
        //遍历车辆列表
        for (Car car : newCarList) {
            //建立中间关系对象
            CarDriver carDriver = new CarDriver();
            //设置司机主键
            carDriver.setDriverId(driver.getId());
            //设置车辆主键
            carDriver.setCarId(car.getId());
            //调用方法插叙新的关系对象
            carDriverMapper.insert(carDriver);
        }
    }

    /**
     * 修改司机信息方法实现(更改图片信息)
     * @param driverJson
     * @param imgJson
     * @param files
     * @param carList
     */
    @Override
    public void updateDriverAll(String driverJson, String imgJson, MultipartFile[] files, String carList) {
        //调用未更改图片信息的方法修改车辆和司机信息
        updateDriver(driverJson, carList);
        //处理图片信息
        //创建json转化对象
        ObjectMapper mapper = new ObjectMapper();
        //把json字符串转换成对象
        Picture picture = null;
        Driver driver = null;
        try {
            driver = mapper.readValue(driverJson, Driver.class);
            picture = mapper.readValue(imgJson, Picture.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        //根据司机主键查询到原始的图片信息和主键
        //创建司机和图片信息中间类条件查询对象
        LambdaQueryWrapper<DriverPicture> driverPictureLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //设置查询条件为与司机主键一致
        driverPictureLambdaQueryWrapper.eq(DriverPicture::getDriverId, driver.getId());
        //根据司机主键查询中间表对象
        DriverPicture driverPicture = driverPictureMapper.selectOne(driverPictureLambdaQueryWrapper);
        //根据图片主键查询数据库中保存的图片
        Picture oldPicture = pictureMapper.selectById(driverPicture.getPictureId());
        //替换图片逻辑
        //设置标记数组，代表当前位置是否更改过
        boolean[] status = new boolean[6];
        /*
        * 因为在前端中，设置图片数组是按1-5的顺序来的，而图片对象也是按1-5的顺序来的
        * 因此，如果有一个位置的图片路径变化，那一定是按照图片数组的顺序来的，因此遍历图片数组
        * 按顺序判断，如果有不同的则更改，但是图片只可能被更改一次
        * */
        for (MultipartFile multipartFile : files) {
            if (!picture.getImgUrl1().equals(oldPicture.getImgUrl1()) && !status[1]) {
                String imgUrl = UploadUtil.uploadImg(multipartFile);
                picture.setImgUrl1(imgUrl);
                status[1] = true;
            } else if (!picture.getImgUrl2().equals(oldPicture.getImgUrl2()) && !status[2]) {
                String imgUrl = UploadUtil.uploadImg(multipartFile);
                picture.setImgUrl2(imgUrl);
                status[2] = true;
            } else if (!picture.getImgUrl3().equals(oldPicture.getImgUrl3()) && !status[3]) {
                String imgUrl = UploadUtil.uploadImg(multipartFile);
                picture.setImgUrl3(imgUrl);
                status[3] = true;
            } else if (!picture.getImgUrl4().equals(oldPicture.getImgUrl4()) && !status[4]) {
                String imgUrl = UploadUtil.uploadImg(multipartFile);
                picture.setImgUrl4(imgUrl);
                status[4] = true;
            } else if (!picture.getImgUrl5().equals(oldPicture.getImgUrl5()) && !status[5]) {
                String imgUrl = UploadUtil.uploadImg(multipartFile);
                picture.setImgUrl5(imgUrl);
                status[5] = true;
            }
        }
        //设置图片的主键
        picture.setId(oldPicture.getId());
        //调用修改方法修改图片信息
        pictureMapper.updateById(picture);
    }
}
